<template>
  <div v-loading="loading" :class="[isShowDetail ? '' : 'bgfff', 'ffu_total']">
    <!-- <px-radio-group v-model="chartType" class="switch-button" size="small" @change="changeChartType">
      <px-radio-button label="桑基图" />
      <px-radio-button label="流程图" />
    </px-radio-group> -->
    <div class="back-wrap">
      <px-button v-show="isShowDetail" type="primary" icon="ArrowLeft" size="small" @click="backClick">返回</px-button>
    </div>
    <div class="switch-wrap">
      <px-switch v-if="chartType === '桑基图' && !isShowDetail" v-model="switchVal" active-text="利用率" @change="switchChange" />
    </div>
    <div v-show="chartType === '桑基图' && !isShowDetail" class="sankey-chart-dom" @wheel.prevent="onWheel">
      <div ref="sankeyChartDomRef" class="sankey-chart" :style="{ scale: wheelScale }" />
    </div>
    <!-- <iframe
      v-show="chartType === '流程图' && !isShowDetail"
      id="preivewFrame"
      class="iframe-con"
      scrolling="no"
      :src="`${VITE_FANRUAN_BASE_URL}/webroot/decision/view/duchamp?viewlet=energy/${templateName}&startTime=${queryParams.startTime}&endTime=${queryParams.endTime}&factory=${queryParams.factory}&op=view`"
      frameborder="0"
    /> -->
    <iframe
      v-if="chartType === '流程图'"
      id="preivewFrame"
      class="iframe-con"
      scrolling="no"
      :src="`${VITE_FANRUAN_BASE_URL}/webroot/decision/view/form?viewlet=energy/${templateName}&startTime=${queryParams.startTime}&endTime=${queryParams.endTime}&factory=${queryParams.factory}&sysId=${sysId}`"
      frameborder="0"
    />
    <div v-show="isShowDetail" class="sankey-detail-wrap">
      <px-row :gutter="16">
        <px-col :span="8">
          <div class="lf-wrap">
            <modelTitle :title="'能源利用'" />
            <div class="item-wrap">
              <div class="black-wrap">
                <div class="item">
                  <div class="img"><SupplyIcon /></div>
                  <div class="rt">
                    <div class="rt-text">上游供给</div>
                    <div class="rt-btm">
                      <span class="num">{{ sankeyDetailObj?.supply || "-" }}</span
                      ><span class="unit">{{ sankeyDetailObj?.unit }}</span>
                    </div>
                  </div>
                </div>
                <div class="item">
                  <div class="img"><ConsumptionIcon /></div>
                  <div class="rt">
                    <div class="rt-text">下游消耗</div>
                    <div class="rt-btm">
                      <span class="num">{{ sankeyDetailObj?.consumption || "-" }}</span
                      ><span class="unit">{{ sankeyDetailObj?.unit }}</span>
                    </div>
                  </div>
                </div>
              </div>
              <div class="black-wrap">
                <div class="item">
                  <div class="img"><LossIcon /></div>
                  <div class="rt">
                    <div class="rt-text">损耗</div>
                    <div class="rt-btm">
                      <span class="num">{{ sankeyDetailObj?.loss || "-" }}</span
                      ><span class="unit">{{ sankeyDetailObj?.unit }}</span>
                    </div>
                  </div>
                </div>
                <div class="item">
                  <div class="img"><RatioIcon /></div>
                  <div class="rt">
                    <div class="rt-text">利用率</div>
                    <div class="rt-btm">
                      <span class="num">{{ sankeyDetailObj?.ratio ? sankeyDetailObj?.ratio : "" || "-" }}</span
                      ><span class="unit">%</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="lf-btm">
              <px-table :data="tableData" stripe size="small" class="table-wrap">
                <px-table-column prop="name" label="下游用户" min-width="120" show-overflow-tooltip />
                <px-table-column prop="consumption" label="消耗量" min-width="80" show-overflow-tooltip />
                <px-table-column prop="ratioText" label="占比" min-width="80" show-overflow-tooltip />
              </px-table>
            </div>
          </div>
        </px-col>
        <px-col :span="16">
          <div class="rt-wrap">
            <modelTitle :title="'耗电量损耗曲线'" />
            <div ref="chartLineRef" class="chart" />
          </div>
        </px-col>
      </px-row>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, computed, reactive, toRefs, getCurrentInstance } from "vue";
import * as echarts from "echarts";
import axios from "axios";
import { useOnWheelHook } from "../hook.js";
import { getFlowAPI, getUseRatioAPI } from "@/api/energy/flow";
import dayjs from "dayjs";
import modelTitle from "@/views/common/components/modelTitle/index.vue";
// svg
import SupplyIcon from "@/assets/svg/energy/flowDiagram/supply.svg?component";
import ConsumptionIcon from "@/assets/svg/energy/flowDiagram/consumption.svg?component";
import LossIcon from "@/assets/svg/energy/flowDiagram/loss.svg?component";
import RatioIcon from "@/assets/svg/energy/flowDiagram/ratio.svg?component";

const { VITE_FANRUAN_BASE_URL } = import.meta.env;

const { proxy } = getCurrentInstance();

const props = defineProps({
  timeType: {
    type: String,
    default: ""
  },
  queryParams: {
    type: Object,
    default: () => {}
  }
});

const chartType = ref("桑基图");
const isShowDetail = ref(false);
const sysId = ref("");
const chartLineRef = ref();

const state = reactive({
  tableData: [],
  sankeyDetailObj: {
    unit: "", //单位
    supply: "", // 供应量
    consumption: "", // 下游消耗量
    loss: "", // 损耗量
    ratio: "", // 利用率
    trend: {
      xaxis: [],
      yaxis: []
    }
  },
  loading: false,
  switchVal: true
});
const { tableData, sankeyDetailObj, loading, switchVal } = toRefs(state);

const templateName = computed(() => {
  switch (props.timeType) {
    case "Daily":
      return (
        encodeURIComponent(encodeURIComponent(isShowDetail.value ? "energyBalanceUseRationDaily" : "energyFlowEquilibriumHotSteamDaily")) + ".frm"
      );
      break;
    case "Monthly":
      return (
        encodeURIComponent(encodeURIComponent(isShowDetail.value ? "energyBalanceUseRationMonthly" : "energyFlowEquilibriumHotSteamMonthly")) + ".frm"
      );
      break;
    case "Yearly":
      return (
        encodeURIComponent(encodeURIComponent(isShowDetail.value ? "energyBalanceUseRationYearly" : "energyFlowEquilibriumHotSteamYearly")) + ".frm"
      );
      break;
    default:
      return (
        encodeURIComponent(encodeURIComponent(isShowDetail.value ? "energyBalanceUseRationMonthly" : "energyFlowEquilibriumHotSteamMonthly")) + ".frm"
      );
      break;
  }
});

onMounted(() => {
  getSankeyData();
  window.addEventListener("message", function (event) {
    let o = `${window.location.protocol}//${window.location.hostname}:8443`;
    if (event.origin !== o) return;
    let msg = event.data;
    let sysId = msg ? msg.split("#")[1].split("=")[1] : "";
    if (sysId) {
      sysId.value = sysId;
    }
  });
});

const changeChartType = val => {
  chartType.value = val;
  isShowDetail.value = false;
};

// 获取桑基图数据
const getSankeyData = () => {
  // axios
  //   .get("/models/energyBalance_hotSteam.json")
  //   .then(res => {
  //     const data = res.data;
  //     nextTick(() => {
  //       drawSankeyChart(data);
  //     });
  //   })
  //   .catch(error => {
  //     console.log(error);
  //   });
  getFlowData();
};

const getFlowData = async () => {
  try {
    state.loading = true;
    const { energyType, startDate, endDate, dimension, percent } = getParams();
    const params = {
      energyType,
      startDate,
      endDate,
      dimension,
      percent
    };
    const res = await getFlowAPI(params);
    nextTick(() => {
      drawSankeyChart(res);
    });
  } catch (error) {
    console.log(error);
  } finally {
    state.loading = false;
  }
};

const sankeyChartDomRef = ref(null);
// 电 桑基图
const drawSankeyChart = data => {
  let myChart = echarts.init(sankeyChartDomRef.value);
  let option = {
    // tooltip: {
    //   trigger: "item",
    //   triggerOn: "mousemove"
    // },
    grid: {
      top: 10
    },
    dataZoom: [
      {
        // 设置滚动条的隐藏或显示
        show: true,
        // 设置类型
        type: "slider",
        // 设置背景颜色
        backgroundColor: "rgb(19, 63, 100)",
        // 设置选中范围的填充颜色
        fillerColor: "rgb(16, 171, 198)",
        // 设置边框颜色
        borderColor: "rgb(19, 63, 100)",
        // 是否显示detail，即拖拽时候显示详细数值信息
        showDetail: false,
        // 数据窗口范围的起始数值
        startValue: 0,
        // 数据窗口范围的结束数值（一页显示多少条数据）
        endValue: 5,
        // 控制哪个轴，如果是number表示控制一个轴，
        // 如果是Array表示控制多个轴。此处控制第二根轴
        yAxisIndex: [0, 1],
        // empty：当前数据窗口外的数据，被设置为空。
        // 即不会影响其他轴的数据范围
        filterMode: "empty",
        // 滚动条高度
        width: 8,
        // 滚动条显示位置
        height: "80%",
        // 距离右边
        right: 3,
        // 控制手柄的尺寸
        handleSize: 0,
        // 是否锁定选择区域（或叫做数据窗口）的大小
        zoomLoxk: true,
        // 组件离容器上侧的距离
        // 如果top的值为'top', 'middle', 'bottom'，组件会根据相应的位置自动对齐
        top: "middle"
      },
      {
        // 没有下面这块的话，只能拖动滚动条，
        // 鼠标滚轮在区域内不能控制外部滚动条
        type: "inside",
        // 控制哪个轴，如果是number表示控制一个轴，
        // 如果是Array表示控制多个轴。此处控制第二根轴
        yAxisIndex: [0, 1],
        // 滚轮是否触发缩放
        zoomOnMouseWheel: false,
        // 鼠标移动能否触发平移
        moveOnMouseMove: true,
        // 鼠标滚轮能否触发平移
        moveOnMouseWheel: true
      }
    ],
    series: [
      {
        type: "sankey",
        data: data.nodes,
        links: data.links,
        emphasis: {
          focus: "adjacency"
        },
        levels: [
          {
            depth: 0,
            itemStyle: {
              color: "#fbb4ae"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          },
          {
            depth: 1,
            itemStyle: {
              color: "#b3cde3"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          },
          {
            depth: 2,
            itemStyle: {
              color: "#ccebc5"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          },
          {
            depth: 3,
            itemStyle: {
              color: "#decbe4"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          },
          {
            depth: 4,
            itemStyle: {
              color: "#9E47C3"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          },
          {
            depth: 5,
            itemStyle: {
              color: "#F1647A"
            },
            lineStyle: {
              color: "source",
              opacity: 0.6
            }
          }
        ],
        lineStyle: {
          curveness: 0.5
        }
      }
    ]
  };
  option && myChart.setOption(option);
  myChart.on("click", function (params) {
    // if (params) {
    //   sysId.value = params.data.source ?? params.name;
    //   isShowDetail.value = true;
    // }
    if (params.componentType === "series" && params.dataType === "node") {
      const nodeName = params.name; // 获取被点击节点的名称
      // 判断是否为末端节点
      const isEndNode = option.series[0].links.every(link => {
        return link.source !== nodeName; // 检查是否存在以该节点为源的边
      });
      if (!isEndNode) {
        sysId.value = params.data.source ?? params.name;
        isShowDetail.value = true;
        // 调用接口
        getUseRatioData();
      }
    } else {
      sysId.value = params.data.source ?? params.name;
      isShowDetail.value = true;
      // 调用接口
      getUseRatioData();
    }
  });
};

// 获取节点利用
const getUseRatioData = async () => {
  try {
    state.loading = true;
    const { energyType, startDate, endDate, dimension } = getParams();
    const params = {
      energyType: energyType,
      startDate: startDate,
      endDate: endDate,
      nodeName: sysId.value,
      dimension: dimension
    };
    const res = await getUseRatioAPI(params);
    if (res) {
      state.sankeyDetailObj = res;
      state.tableData =
        res?.table?.map(i => {
          return {
            ratioText: (i.ratioText = i.ratio + "%"),
            consumption: i.consumption,
            name: i.name
          };
        }) || [];
    }
    res?.trend?.yaxis?.length ? drawLineChart(chartLineRef.value, res?.trend, res?.unit) : "";
  } catch (error) {
    console.log(error);
  } finally {
    state.loading = false;
  }
};

// 画折线图
const drawLineChart = (dom, obj, unit) => {
  if (dom) {
    let options = {
      toolbox: {
        show: true,
        feature: {
          saveAsImage: {
            title: "点击保存为图片"
          }
        }
      },
      tooltip: {
        formatter: function (params) {
          const value = params.value;
          return `时间: ${params.name}<br>数值: ${value}${unit}`;
        }
      },
      grid: {
        bottom: "10%"
      },
      xAxis: {
        type: "category",
        data: obj?.xaxis || []
      },
      yAxis: {
        type: "value",
        name: unit || obj?.yaxis[0]?.unit || "", // 为 Y 轴添加文本
        axisLabel: {
          formatter: function (value) {
            if (value === 0) {
              return value;
            }
            const absValue = Math.abs(value);

            // 极大数值使用科学计数法
            if (absValue >= 1e15) {
              return value.toExponential(2);
            }
            const units = ["", "K", "M", "B", "T"];
            const order = Math.min(Math.floor(Math.log10(absValue) / 3), units.length - 1);
            const unitValue = absValue / Math.pow(10, order * 3);
            return (value < 0 ? "-" : "") + unitValue.toFixed(2) + units[order];
          }
        }
      },
      series: [
        {
          data: obj?.yaxis?.[0]?.value || [],
          type: "line",
          smooth: true
        }
      ]
    };
    let myChart = echarts.init(dom);
    myChart.clear();
    myChart.setOption(options);
    myChart.resize();
  }
};

const getParams = () => {
  let energyType = "hotSteam";
  let startDate = props.queryParams.startTime || dayjs().format("YYYY-MM") + "-01 00:00:00";
  let endDate = props.queryParams.endTime || dayjs().format("YYYY-MM") + "-01 23:59:59";
  let obj = {
    Daily: "D",
    Monthly: "M",
    Yearly: "Y"
  };
  let dimension = obj[props.timeType] || "";
  let percent = state.switchVal ? "YES" : "NO";
  return {
    energyType,
    startDate,
    endDate,
    dimension,
    percent
  };
};

const backClick = () => {
  isShowDetail.value = false;
};
const switchChange = () => {
  getFlowData();
};
// 导出
const handleExport = () => {
  const { energyType, startDate, endDate, dimension, percent } = getParams();
  const params = {
    energyType,
    startDate,
    endDate,
    dimension,
    percent
  };
  proxy.download("post", "/energy/balance/exportFlow", params, "能源平衡-能流图-蒸汽/热水.xlsx");
};
// 滚动缩小
const { wheelScale, onWheel } = useOnWheelHook();
// 获取数据
const getData = () => {
  getSankeyData();
  getUseRatioData();
};
defineExpose({
  getData,
  handleExport
});
</script>

<style lang="scss" scoped>
@import url("@/views/common/energy/reused/flowDiagram/component/index.scss");
</style>
